from enum import Enum
from typing import List, Callable

class States(Enum):
    RUNNING = 1
    EXIT = 2
    ENTRY = 3

class State:
    def __init__(self, entry: Callable[[], States], action: Callable[[], None] = None):
        self.entry = entry
        self.action = action
        self.end = None
        self.PRI = 0

class FSM:
    def __init__(self):
        self.curr = None
        self.total_num = 0
        self.state_list: List[State] = []
        self.on_change = None

    def create(self, entry: Callable[[], States], action: Callable[[], None] = None) -> State:
        state = State(entry, action)
        self.add(state)
        return state

    def add(self, state: State):
        state.PRI = self.total_num
        if state.PRI == 0:
            self.curr = state
        self.state_list.append(state)
        self.total_num += 1

    def transit(self, pri: int):
        next_state = self.state_list[pri]
        if self.curr.end:
            self.curr.end()
        if self.on_change:
            self.on_change(f"{self.curr.PRI} ==> {next_state.PRI}")
        self.curr = next_state

    def all_eing(self):
        if self.curr.action:
            self.curr.action()
        for state in self.state_list:
            if state.PRI != 0 and state.entry() == States.ENTRY and state.PRI != self.curr.PRI:
                if state.PRI < self.curr.PRI:
                    continue
                self.transit(state.PRI)
        if self.curr.entry() == States.EXIT:
            self.curr = self.state_list[0]



import time

class FSMTest:
    def __init__(self):
        self.fsm = FSM()
        self.i = 5.0
        def on_change(info):
            print(info)

        self.fsm.on_change = on_change

        # Example FSM state creations (commented out)
        # self.fsm.create(lambda: True, lambda: None)
        self.fsm.create(lambda: self.entry_condition(), lambda: print("11111"))
        self.fsm.create(lambda: self.entry_condition2(), lambda: print("22222"))

    def entry_condition(self):
        self.i -= 1  # Replace with time decrement logic if needed
        return States.ENTRY if self.i <= 0 else States.RUNNING

    def entry_condition2(self):
        return States.ENTRY if self.i <= 2 else States.RUNNING

    def update(self):
        self.fsm.all_eing()

# Example usage
if __name__ == "__main__":
    fsm_test = FSMTest()
    while True:  # Replace with actual game loop condition
        fsm_test.update()
        time.sleep(1)  # Replace with actual game loop timing
